#!/usr/bin/env python3
"""
二维码管理路由
"""

from datetime import datetime
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy.future import select

from app.database.session import get_db
from app.models.visitor import Visitor
from app.models.verification_record import VerificationRecord as VerificationRecordModel
from app.schemas.qrcode import QRCodeRequest, QRCodeResponse
from app.schemas.verification_record import VerificationRecord, VerificationRecordListResponse
from app.services.audit_service import audit_log
from app.services.qrcode_service import qrcode_service

router = APIRouter()


@router.post("/generate", response_model=QRCodeResponse)
async def generate_qrcode(request: QRCodeRequest, db: AsyncSession = Depends(get_db)):
    """
    生成访客二维码

    Args:
        request: 二维码生成请求
        db: 数据库会话

    Returns:
        QRCodeResponse: 二维码响应
    """
    try:
        # 验证访客是否存在
        result = await db.execute(select(Visitor).where(Visitor.id == request.visitor_id))
        visitor = result.scalar_one_or_none()

        if not visitor:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="访客不存在")

        # 准备访客数据
        visitor_data = {
            "visitor_id": visitor.id,
            "name": visitor.name,
            "id_card": visitor.id_card,
            "company": visitor.company,
            "visit_reason": visitor.visit_reason,
            "interviewee": visitor.interviewee,
            "is_special": visitor.is_special,
        }

        # 生成二维码
        qr_code_data = await qrcode_service.generate_visitor_qrcode(visitor_data)

        # 更新访客记录中的二维码信息
        visitor.qr_code = qr_code_data
        visitor.qr_code_expire_time = None  # 由二维码服务内部处理过期时间

        await db.commit()
        await db.refresh(visitor)

        # 记录审计日志
        await audit_log(
            db=db,
            operator="system",
            operation_type="generate_qrcode",
            operation_target="qrcode",
            operation_details={"visitor_id": visitor.id},
            related_visitor_id=visitor.id,
            related_qrcode=qr_code_data,
        )

        return QRCodeResponse(
            qr_code=qr_code_data,
            visitor_id=visitor.id,
            visitor_name=visitor.name,
            message="二维码生成成功",
            verification_result=None,
            created_at=None,
            expire_time=None
        )

    except HTTPException:
        raise
    except Exception as e:
        await db.rollback()
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"生成二维码失败: {str(e)}")


@router.post("/verify", response_model=QRCodeResponse)
async def verify_qrcode(request: QRCodeRequest, db: AsyncSession = Depends(get_db)):
    """
    验证二维码

    Args:
        request: 二维码验证请求
        db: 数据库会话

    Returns:
        QRCodeResponse: 验证结果响应
    """
    try:
        # 验证二维码数据是否存在
        if not request.qr_code:
            # 记录验证失败的审计日志
            await audit_log(
                db=db,
                operator="scanner",
                operation_type="verify_qrcode",
                operation_target="qrcode",
                success=False,
                error_message="二维码数据为空",
                related_qrcode=request.qr_code,
            )
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="二维码数据为空")
        
        # 验证二维码
        visitor_data = await qrcode_service.verify_qrcode(request.qr_code)

        # 验证访客访问权限
        access_result = await qrcode_service.validate_visitor_access(visitor_data)

        if not access_result["valid"]:
            # 记录验证失败的审计日志
            await audit_log(
                db=db,
                operator="scanner",
                operation_type="verify_qrcode",
                operation_target="qrcode",
                success=False,
                error_message=access_result["error"],
                related_qrcode=request.qr_code,
            )
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=access_result["error"])

        # 获取访客信息
        result = await db.execute(select(Visitor).where(Visitor.id == visitor_data["visitor_id"]))
        visitor = result.scalar_one_or_none()

        if not visitor:
            # 记录验证失败的审计日志
            await audit_log(
                db=db,
                operator="scanner",
                operation_type="verify_qrcode",
                operation_target="qrcode",
                success=False,
                error_message="访客不存在",
                related_qrcode=request.qr_code,
            )
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="访客不存在")

        # 更新访客状态为访问中
        if visitor.status == "approved":
            visitor.status = "visiting"
            visitor.actual_visit_time = None  # 实际访问时间由前端记录
            await db.commit()

        # 创建核验记录
        verification_record = VerificationRecordModel(
            visitor_id=visitor.id,
            visitor_name=visitor.name,
            visitor_phone=visitor.phone,
            visitor_type="special" if visitor.is_special else "regular",
            special_visitor_flag=visitor.is_special,
            qr_code_content=request.qr_code,
            verify_time=None,  # 由数据库默认值设置
            verify_result="success",
            guard_id=1,  # 暂时设置为1，实际应该由前端传入或从认证中获取
            guard_name="系统门卫",  # 暂时设置为系统门卫，实际应该从认证中获取
            guard_point="主入口",  # 暂时设置为主入口，实际应该由前端传入
        )
        
        db.add(verification_record)
        await db.commit()
        await db.refresh(verification_record)

        # 记录审计日志
        await audit_log(
            db=db,
            operator="scanner",
            operation_type="verify_qrcode",
            operation_target="qrcode",
            operation_details={"visitor_id": visitor.id, "verification_result": access_result},
            related_visitor_id=visitor.id,
            related_qrcode=request.qr_code,
        )

        return QRCodeResponse(
            qr_code=request.qr_code,
            visitor_id=visitor.id,
            visitor_name=visitor.name,
            message="二维码验证成功",
            verification_result=access_result,
            created_at=None,
            expire_time=None
        )

    except HTTPException:
        raise
    except Exception as e:
        # 记录通用错误日志
        await audit_log(
            db=db,
            operator="scanner",
            operation_type="verify_qrcode",
            operation_target="qrcode",
            success=False,
            error_message=str(e),
            related_qrcode=request.qr_code,
        )
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"验证二维码失败: {str(e)}")


@router.get("/verification-records/{record_id}", response_model=VerificationRecord)
async def get_verification_record(
    record_id: int,
    db: AsyncSession = Depends(get_db)
):
    """
    获取单个核验记录

    Args:
        record_id: 核验记录ID
        db: 数据库会话

    Returns:
        VerificationRecord: 核验记录详情
    """
    result = await db.execute(select(VerificationRecordModel).where(VerificationRecordModel.id == record_id))
    record = result.scalar_one_or_none()

    if not record:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=f"核验记录ID {record_id} 不存在"
        )

    return record


@router.get("/verification-records", response_model=VerificationRecordListResponse)
async def get_verification_records(
    skip: int = 0,
    limit: int = 10,
    visitor_name: str | None = None,
    verify_result: str | None = None,
    start_time: str | None = None,
    end_time: str | None = None,
    db: AsyncSession = Depends(get_db)
):
    """
    获取核验记录列表（带分页和筛选）

    Args:
        skip: 跳过的记录数
        limit: 限制返回的记录数
        visitor_name: 按访客姓名筛选
        verify_result: 按核验结果筛选
        start_time: 按开始时间筛选
        end_time: 按结束时间筛选
        db: 数据库会话

    Returns:
        VerificationRecordListResponse: 核验记录列表
    """
    query = select(VerificationRecordModel).order_by(VerificationRecordModel.verify_time.desc())

    # 添加筛选条件
    if visitor_name:
        query = query.where(VerificationRecordModel.visitor_name.contains(visitor_name))
    if verify_result:
        query = query.where(VerificationRecordModel.verify_result == verify_result)
    if start_time:
        query = query.where(VerificationRecordModel.verify_time >= datetime.fromisoformat(start_time))
    if end_time:
        query = query.where(VerificationRecordModel.verify_time <= datetime.fromisoformat(end_time))

    # 计算总数
    total_query = select(VerificationRecordModel.id)
    if visitor_name:
        total_query = total_query.where(VerificationRecordModel.visitor_name.contains(visitor_name))
    if verify_result:
        total_query = total_query.where(VerificationRecordModel.verify_result == verify_result)
    if start_time:
        total_query = total_query.where(VerificationRecordModel.verify_time >= datetime.fromisoformat(start_time))
    if end_time:
        total_query = total_query.where(VerificationRecordModel.verify_time <= datetime.fromisoformat(end_time))

    total_result = await db.execute(total_query)
    total = len(total_result.scalars().all())

    # 获取分页数据
    query = query.offset(skip).limit(limit)
    result = await db.execute(query)
    records = result.scalars().all()

    return VerificationRecordListResponse(
        records=list(records),
        total=total,
        skip=skip,
        limit=limit
    )
